package com.skivingcloud.admin.sys.service.impl;

import com.skivingcloud.admin.sys.entity.SysBusinessCommon;
import com.skivingcloud.admin.sys.entity.SysBusinessDesigner;
import com.skivingcloud.admin.sys.entity.User;
import com.skivingcloud.admin.sys.feignclient.FWorkflowTaskServices;
import com.skivingcloud.admin.sys.mapper.SysBusinessCommonMapper;
import com.skivingcloud.admin.sys.mapper.SysBusinessDesignerMapper;
import com.skivingcloud.admin.sys.service.ISysBusinessCommonService;
import com.skivingcloud.common.exception.BusinessException;
import com.skivingcloud.common.utils.PageUtils;
import com.skivingcloud.common.utils.R;
import com.skivingcloud.common.utils.UuidUtil;

import net.sf.json.JSONObject;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * <p>
 * 通用业务数据表(业务的表单数据） 服务实现类
 * </p>
 *
 * @author skivingcloud
 * @since 2022-07-07
 */
@Service
public class SysBusinessCommonServiceImpl extends ServiceImpl<SysBusinessCommonMapper, SysBusinessCommon> implements ISysBusinessCommonService {

	@Autowired
	private FWorkflowTaskServices workflowTaskServices;
	@Autowired
	private SysBusinessDesignerMapper sysBusinessDesignerMapper;
	
	@Override
	public PageUtils queryPage(Map<String, Object> params) {
		PageUtils pageUtils = PageUtils.getPageInfo(params);
		Page<SysBusinessCommon> p = PageHelper.startPage(pageUtils.getPage(), pageUtils.getLimit());
		SysBusinessCommon sysBusinessCommon = (SysBusinessCommon) JSONObject.toBean(
				JSONObject.fromObject(params.get("dataForm")),
				SysBusinessCommon.class);
		QueryWrapper<SysBusinessCommon> queryWrapper = new QueryWrapper<>();
		if (StringUtils.isNotBlank(sysBusinessCommon.getDesignerCode())) {
			queryWrapper.like("designer_code", "%" + sysBusinessCommon.getDesignerCode() + "%");
		}
		this.baseMapper.selectList(queryWrapper);
		pageUtils = new PageUtils(p);
		return pageUtils;
	}

	@Override
	public void add(SysBusinessCommon sysBusinessCommon, User user) {
		sysBusinessCommon.setId(UuidUtil.get32UUID());
		sysBusinessCommon.setVersion(1);
		sysBusinessCommon.setCreateTime(LocalDateTime.now());
		sysBusinessCommon.setCreater(user.getId());
		sysBusinessCommon.setTenantId(user.getTenantId());
		this.baseMapper.insert(sysBusinessCommon);
	}

	@Override
	public void update(SysBusinessCommon sysBusinessCommon, User user) {
		sysBusinessCommon.setVersion(sysBusinessCommon.getVersion() + 1);
		sysBusinessCommon.setModUser(user.getId());
		sysBusinessCommon.setModTime(LocalDateTime.now());
		this.baseMapper.updateById(sysBusinessCommon);
	}

	@Override
	public void deleteBatch(String[] ids) {
		this.baseMapper.deleteBatchIds(Arrays.asList(ids));
	}

	@Override
	public SysBusinessCommon selectById(String id) {
		return this.baseMapper.selectById(id);
	}

	/**
	 * 通用的业务提交方法，以json格式村塾表单数据，如果定义了工作流则会启动一个流程
	 * 
	 * @param jsonNode
	 * @param user
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
    public void submitBusinessCommonAdd(JsonNode jsonNode, User user) throws Exception{
		SysBusinessCommon sysBusinessCommon = new SysBusinessCommon();
		sysBusinessCommon.setId(UuidUtil.get32UUID());
		sysBusinessCommon.setVersion(1);
		sysBusinessCommon.setCreateTime(LocalDateTime.now());
		sysBusinessCommon.setCreater(user.getId());
		sysBusinessCommon.setTenantId(user.getTenantId());
		sysBusinessCommon.setDesignerId(jsonNode.get("designerId").asText());
		sysBusinessCommon.setDesignerCode(jsonNode.get("designerCode").asText());
		JsonNode formData = jsonNode.get("formData");
		ObjectNode objectNode = (ObjectNode) formData;
		objectNode.put("id", sysBusinessCommon.getId());
		sysBusinessCommon.setFormData(objectNode);
		this.baseMapper.insert(sysBusinessCommon);
		if(jsonNode.findValue("taskParams") != null){
			if(jsonNode.get("taskParams").findValue("taskDefCode") != null
				&& StringUtils.isNotBlank(jsonNode.get("taskParams").get("taskDefCode").asText())) {
				SysBusinessDesigner sysBusinessDesigner = sysBusinessDesignerMapper.selectById(jsonNode.get("designerId").asText());
				//调用流程发起接口
				Map<String, Object> taskParam = new LinkedHashMap<>();
				taskParam.put("busNo", sysBusinessCommon.getId());
				taskParam.put("tenantId", user.getTenantId());
				taskParam.put("processKey", jsonNode.get("taskParams").get("taskDefCode").asText());
				taskParam.put("briefReport", user.getStaffName() + "-" + sysBusinessDesigner.getDesignerName());
				//将业务设计的id设置流程为变量
				Map<String, Object> wParam = new LinkedHashMap<>();
				wParam.put("businessDesignerId", sysBusinessDesigner.getId());
				wParam.put("businessDesignerCode", sysBusinessDesigner.getDesignerCode());
				taskParam.put("wf_param", wParam);
				R r = workflowTaskServices.subminTask(taskParam);
				if ((Integer) r.get("code") != 0) {
					throw new BusinessException(r.get("msg").toString());
				}
			}
		}
	}

	/**
	 * 通用的业务提交方法，以json格式存储表单数据，如果定义了工作流则会提交流程流转
	 * 
	 * @param jsonNode
	 * @param user
	 * @throws Exception
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
    public void submitBusinessCommonUpdate(JsonNode jsonNode, User user) throws Exception {
		String busId = jsonNode.get("busId").asText();
		SysBusinessCommon sysBusinessCommon = this.baseMapper.selectById(busId);
		sysBusinessCommon.setVersion(sysBusinessCommon.getVersion() + 1);
		JsonNode formData = jsonNode.get("formData");
		ObjectNode objectNode = (ObjectNode) formData;
		objectNode.put("id", sysBusinessCommon.getId());
		sysBusinessCommon.setFormData(objectNode);
		sysBusinessCommon.setModUser(user.getId());
		sysBusinessCommon.setModTime(LocalDateTime.now());
		this.baseMapper.updateById(sysBusinessCommon);
		if (jsonNode.findValue("taskParams") != null) {
			ObjectMapper mapper = new ObjectMapper();
			// 调用流程发起接口
			Map<String, Object> taskParam = mapper.convertValue(jsonNode.get("taskParams"),
					new TypeReference<Map<String, Object>>() {});
			R r = workflowTaskServices.subminTask(taskParam);
			if ((Integer) r.get("code") != 0) {
				throw new BusinessException(r.get("msg").toString());
			}
		}
	}

}
